import { useEffect, useRef, useState } from "react";
import { message, Select, Button } from "antd";

// 音量监测
import SoundMeter from "../../assets/libs/soundmete";


let audioCtx; // 音频上下文
let soundmete; // 音量监测器
let stream; // 音频流
let recorder; // 录音器

let ws = null; // websocket 实例


import APIS from '../../api'

/**
 * 📢模块
 * @returns
 */
const Board = () => {
  const [num, setNum] = useState(0); // 音频音量
  const [isMicorphoneOn, setIsMecorphoneOn] = useState(false);

  const audioRef = useRef(null); // audio


  // 开启音频录制命令
  const startCMD = async () => {
    console.log('发送音频开始命令')
    //TODO: id
    const res = await APIS.startPushRadioStreamCMDById(1234)
    console.log('发送开播指令')
    console.log(res)
  }

  // 关闭命令
  const stopCMD = async () => {
    console.log('发送音频停止命令')
    const res = await APIS.stopPushRadioStreamCMDById(1234)
    console.log(res)
  }

  // 建立 websocket 连接
  useEffect(() => {
    console.log('准备建立ws')
    ws = new WebSocket('ws://192.168.10.112:8081/client');
    window.ws = ws;
    console.log('ws', ws.readyState)

    ws.addEventListener('open', e => {
      console.log(e)
    })
    ws.addEventListener('message', (e) => {
      console.log('ws message: ', e);
    })
    ws.addEventListener('error', err => {
      console.log('ws error', err)
    })
    ws.addEventListener('close', e => {
      console.log('ws close');
    })
    return () => {
      ws = null
      //安全起见， 关闭
      stopCMD()
    }
  }, []);

  // 音量检测
  const soundMeterStep = () => {
    try {
      audioCtx = new AudioContext(); // 音频上下文
      soundmete = new SoundMeter(audioCtx);
    } catch (err) {
      message.error("网页音频API接口不支持");
    }
    // 声音测量
    soundmete.connectToSource(stream);

    // 通过定时器获取声音测量值 并修改 state 音量值
    const soundMeterProcess = () => {
      const val = soundmete && soundmete.instant.toFixed(2) * 348 + 1;
      setNum(val);
      setTimeout(soundMeterProcess, 200);
    };
    setTimeout(soundMeterProcess, 200);
  };

  // 音频录制
  const record = () => {
    console.log('调用录制')
    // 初始化recoder
    const _recorder = new MediaRecorder(stream, {
      mimeType: "audio/webm",
      audioBitsPerSecond: 12800,
    });
    _recorder.onerror = (e) => {
      message.error("录制发生错误");
      console.log(e);
    };
    _recorder.ondataavailable = (e) => {
      console.log("on dataavailable");
      const { data } = e;
      if (data.size > 0) {
        // 发送数据
        handleSendData(data)
      }
    };
    _recorder.onstop = (e) => {
      console.log("录制停止");
    };
    recorder = _recorder
    // 开始录制
    recorder.start(100); // 录制时间
  };

  // 处理 发送 录制数据
  const handleSendData = data => {

    if (ws && ws.readyState === WebSocket.OPEN) {
      console.log('发送数据大小 ', data.size)
      try {
        ws.send(data)
      } catch (err) {
        console.log('发送数据异常', err)
      }
    } else {
      console.log('连接断开')
    }
  }

  const showAudio = () => {
    const audio = audioRef.current
    audio.srcObject = stream
  }

  // 打开麦克风
  const openMegaphone = () => {

    // 设置麦克风状态为开启
    setIsMecorphoneOn(true)

    // 发送开启命令
    startCMD()

    // 获取流进行录制
    navigator.mediaDevices
      .getUserMedia({ audio: true, video: false })
      .then((mediaStream) => {
        stream = mediaStream;
        // 音频监测
        soundMeterStep();
        // audio组件显示，播放声音
        // showAudio()
        // 录制
        record();
      })
      .catch((err) => {
        console.error(err)
        message.warning("请允许浏览器使用音频");
      });
  };

  // 关闭话筒
  const cloaseMegaphone = () => {
    //设置麦克风状态为关闭
    setIsMecorphoneOn(false)
    console.log('关闭话筒')
    // 关闭音频流
    stream && stream.getTracks().forEach(track => track.stop())
    // 关闭 recorder
    recorder && recorder.stop()
    // 关闭 测量音量 连接
    soundmete && soundmete.stop()

    // 音量置0
    setNum(0);

    stream = null;
    recorder = null;
    soundmete = null;

    // 发送关闭命令
    stopCMD()
  }

  return (
    <div>
      <p>你可以选对应的喇叭，录制声音或者上传音频文件</p>
      {/* <Select style={{ width: 150 }}>
        <Select.Option value="a">喇叭1</Select.Option>
        <Select.Option value="b">喇叭2</Select.Option>
        <Select.Option value="c">喇叭3</Select.Option>
      </Select> */}
      <Button onClick={openMegaphone} disabled={isMicorphoneOn}>点击喊话</Button>
      <Button onClick={cloaseMegaphone} disabled={!isMicorphoneOn}>结束喊话</Button>
      {/* 声音音量条 */}
      <div
        style={{
          width: num + "px",
          height: 10,
          backgroundColor: "#8dc63f",
          margin: "20px 4px",
          animation: "all",
        }}
      ></div>
      <audio ref={audioRef} autoPlay playsInline></audio>
    </div>
  );
};

export default Board;
